#pragma once

#include <GL/glut.h>
#include <Cg/cg.h>
#include <Cg/cgGL.h>


enum ProgramType
{
	PROGRAM_VERTEX,
	PROGRAM_FRAGMENT,
	PROGRAM_GEOMETRY
};


class CgProgram
{
public:
	CgProgram(char*  vpFilename = 0, char* vpEntryPoint = 0, char* fpFileName = 0, char* fpEntryPoint = 0,
		char* gpFileName = 0, char* gpEntryPoint = 0);
	~CgProgram();	

	void SetProgramFiles(char* vertexfile = 0, char* fragmentfile = 0, char* gemotryfile = 0)
	{
		m_VertexProgramFilename=vertexfile;
		m_FragmentProgramFilename=fragmentfile;
	}
	void SetProgramEntries(char* vertexentry = 0, char* fragmententry = 0, char* geometryentry = 0)
	{
		m_VertexProgramEntry=vertexentry;
		m_FragmentProgramEntry=fragmententry;
	}

	void InitPrograms();	

	void SetVertexParam1f(char* paramname,float param)
	{
		if(m_VertexProgram)
			cgSetParameter1f(cgGetNamedParameter(*m_VertexProgram,paramname),param);
	}
	void SetFragmentParam1f(char* paramname,float param)
	{
		if(m_FragmentProgram)
			cgSetParameter1f(cgGetNamedParameter(*m_FragmentProgram,paramname),param);
	}
	void SetGeometryParam1f(char* paramname,float param)
	{
		if(m_GeometryProgram)
			cgSetParameter1f(cgGetNamedParameter(*m_GeometryProgram,paramname),param);
	}
	void SetVertexParam2f(char* paramname,float param1,float param2)
	{
		if(m_VertexProgram)
			cgSetParameter2f(cgGetNamedParameter(*m_VertexProgram,paramname),param1,param2);
	}
	void SetFragmentParam2f(char* paramname,float param1,float param2)
	{
		if(m_FragmentProgram)
			cgSetParameter2f(cgGetNamedParameter(*m_FragmentProgram,paramname),param1,param2);
	}
	void SetGeometryParam2f(char* paramname,float param1,float param2)
	{
		if(m_GeometryProgram)
			cgSetParameter2f(cgGetNamedParameter(*m_GeometryProgram,paramname),param1,param2);
	}
	void SetGeometryParam3f(char* paramname,float param1,float param2,float param3)
	{
		if(m_GeometryProgram)
			cgSetParameter3f(cgGetNamedParameter(*m_GeometryProgram,paramname),param1,param2,param3);
	}
	void SetFragmentParam2i(char* paramname,float param1,float param2)
	{
		if(m_FragmentProgram)
			cgSetParameter2i(cgGetNamedParameter(*m_FragmentProgram,paramname),param1,param2);
	}
	void SetVertexParam3f(char* paramname,float param1,float param2,float param3)
	{
		if(m_VertexProgram)
			cgSetParameter3f(cgGetNamedParameter(*m_VertexProgram,paramname),param1,param2,param3);
	}
	void SetFragmentParam3f(char* paramname,float param1,float param2,float param3)
	{
		if(m_FragmentProgram)
			cgSetParameter3f(cgGetNamedParameter(*m_FragmentProgram,paramname),param1,param2,param3);
	}
	void SetVertexParam4f(char* paramname,float param1,float param2,float param3,float param4)
	{
		if(m_VertexProgram)
			cgSetParameter4f(cgGetNamedParameter(*m_VertexProgram,paramname),param1,param2,param3,param4);
	}
	void SetFragmentParam4f(char* paramname,float param1,float param2,float param3,float param4)
	{
		if(m_FragmentProgram)
			cgSetParameter4f(cgGetNamedParameter(*m_FragmentProgram,paramname),param1,param2,param3,param4);
	}	

	void SetVertexTexParam(char* param,unsigned int TexID)
	{
		if(m_VertexProgram)
			cgGLSetTextureParameter(cgGetNamedParameter(*m_VertexProgram,param),TexID);
	}	
	void SetFragmentTexParam(char* param,unsigned int TexID)
	{
		if(m_FragmentProgram)
			cgGLSetTextureParameter(cgGetNamedParameter(*m_FragmentProgram,param),TexID);
	}

	void SetGeometryTexParam(char* param,unsigned int TexID)
	{
		if(m_GeometryProgram)
			cgGLSetTextureParameter(cgGetNamedParameter(*m_GeometryProgram,param),TexID);
	}	

	void DisableFragmentTexParam(char* param)
	{
		if(m_FragmentProgram)
			cgGLDisableTextureParameter(cgGetNamedParameter(*m_FragmentProgram,param));
	}
	void EnableFragmentTexParam(char* param)
	{
		if(m_FragmentProgram)
			cgGLEnableTextureParameter(cgGetNamedParameter(*m_FragmentProgram,param));
	}
	void DisableVertexTexParam(char* param)
	{
		if(m_VertexProgram)
			cgGLDisableTextureParameter(cgGetNamedParameter(*m_VertexProgram,param));
	}
	void EnableVertexTexParam(char* param)
	{
		if(m_VertexProgram)
			cgGLEnableTextureParameter(cgGetNamedParameter(*m_VertexProgram,param));
	}

	void SetVertexMatrixParam(char* param, double* matrix)
	{
		if (m_VertexProgram)
			cgGLSetMatrixParameterdc(cgGetNamedParameter(*m_VertexProgram,param), matrix);
	}

	void SetFragmentMatrixParam(char* param, double* matrix)
	{
		if (m_FragmentProgram)
			cgGLSetMatrixParameterdc(cgGetNamedParameter(*m_FragmentProgram,param), matrix);
	}

	char* m_FragmentProgramFilename;
	char* m_VertexProgramFilename;
	char* m_GeometryProgramFilename;
	char* m_FragmentProgramEntry;
	char* m_VertexProgramEntry;
	char* m_GeometryProgramEntry;

	CGcontext m_Context;
	CGprogram *m_VertexProgram;
	CGprogram *m_FragmentProgram;
	CGprogram *m_GeometryProgram;
	CGprofile m_VertexProfile, m_FragmentProfile, m_GeometryProfile;

	void Enable();
	void Disable();
};